---
title: L2TP tunnel router via Andrews and Arnold Ltd (AAISP)
x-toc-enable: true
...

[This guide was originally published on
vimuser.org](https://vimuser.org/l2tp.html)

This guide is largely targeted at UK residents, using ISP
[Andrews and Arnold Ltd](https://www.aa.net.uk/) - a similar guide
should be written, generically, for how to set up your own tunnel
server, but no such guide yet exists on Fedfree.

Introduction
============

In this tutorial, we will set up a tunnel connection using Andrews & Arnold
Ltd (A&A) [L2TP tunnel service](https://www.aa.net.uk/broadband/l2tp-service/).
This is basically similar to most VPN services, but you get a lot more freedom
and flexibility e.g. IPv4 subnets (for example, you could host your own DNS on
this).

It could also just be used for normal day to day internet tasks. A&A provide
you with an *unfiltered* service, unshaped and unthrottled in any way.

Brief technical overview
------------------------

Adapt this guide according to your needs. Basically all we want to do is do
PPP via L2TP and enable packet forwarding in Linux, so that packets can
pass between two interfaces. We then set routes. We will have these interfaces:

* `eth0`: WAN port (ethernet) - upstream ISP via `192.168.0.1/24`
* `eth1`: LAN port (ethernet) - only routed over the tunnel `ppp-aaisp-l2tp`:
* `ppp-aaisp-l2tp`: tunnel port (ppp over l2tp), going out via `eth0`

L2TP is a protocol used for to tunnel traffic on the internet. It's quite
commonly used by ISPs to connect customers up to their backend, where they
then provide a PPP login.

So long as you have an *ethernet port* available to use for internet, your tunnel
router can work nicely. If you need to, you *could* set up a WiFi connection or 4G
tether on another machine, sharing that over an RJ45 ethernet port for your L2TP
router to connect to; for example,
raspberry pi USB tethered to 4G LTE service via dongle, assigned IPs presumably
on NAT+DHCP, via ethernet.

Traffic will be forced, via static route, to A&A's L2TP tunnel server. In this
way, *all* traffic will go through L2TP and nothing else. It is completely
isolated from your main network. With this setup, you can host your servers
anywhere, and move them very easily.

Redundant routing
-----------------

If you have *more than one* physical internet connections, you can set up
redundant routing. This may be useful, to reduce downtime.

[*A follow-up guide* is also available, showing how to add redundant routes
via backup internet service](debian-l2tp-aaisp-redundant.md), which you might
consider after successfully making a router based in *this* tutorial.

The `libreboot.org` (also `fedfree.org`) server is literally hosted behind a
redundant routing setup, based on the guide linked above.

Follow *this* guide, on the page you're reading now, before moving on to the
redundancy tutorial. It is important first to simply get your tunnel up and
running, before tweaking it any further, as tunnel routing can be a bit fiddly
to start with.

Preparation
===========

Hardware
--------

You need a computer with 2 ethernet interfaces on it (RJ45). You then need to
run either Linux or BSD on that. For the purpose of this tutorial, I will tell
you how to configure *Debian Linux*, but the information here can be adapted
for any other system. I really only recommend hosting this on BSD or Linux.

Interface names
---------------

In my case, I had these physical interfaces:

* `eth0` is configured via NAT address to normal ISP router, and static route
  to A&A's L2TP server. Client-side L2TP shall connect through this
* `eth1` is for routing IPs from the L2TP, to a switch. this is basically my LAN
  port

Yours may differ, so adapt accordingly.

Getting started
===============

When you first install Debian on the router, you might aswell just use the
net installer. Install *only* the base system (`Standard system utilities`
selected in `tasksel`). You might also enable SSH, if you wish.

Before you actually configure the routing, your Debian machine must *have*
internet so that you can download packages. Alternatively, you might have
apt configured to fetch them from installation media. It's up to you, really.

You must install *these* packages:
 
	apt-get install ppp pppoe xl2tpd iproute2 tcpdump net-tools resolvconf

You should install these packages BEFORE doing anything else. Just connect
via DHCP or something and install these. You could also grab them from
Debian installation media.

If you need a decent text editor, might I suggest [Vim](https://www.vim.org/).
As scandalous as it may seem, Debian doesn't install it by default!

Network configuration
=====================

MAKE SURE you have the packages installed, as listed above, before continuing.
At this point, we dive straight in and configure everything.

For our purposes, the WAN side on the router will connect to the internet
via NAT, through the main ISPs network, but we will not use DHCP. Instead,
a static (NAT) IP address will be specified, but with no gateway; in so doing,
no default route will be set, but we will set a static route.

The static route will only route traffic to `90.155.53.19` which is A&A's L2TP
server, via what would otherwise be a gateway IP, in my case `192.168.0.1`, but
in your case that might be `192.168.1.1`. You must adapt accordingly.

By setting the static route this way, we can only connect to A&A L2TP when the
tunnel connection is down. When it's up, we still have no default route but
then we add a default route, going through the PPP tunnel via L2TP. In this
way, all traffic (except traffic to `90.155.53.19` directly) will go through
the L2TP tunnel, NOT your main upstream ISP (e.g. Virgin, Sky, TalkTalk). By
doing this, we ensure that all traffic correctly goes through *A&A* only.

The reason we use A&A's IP address directly, is because we don't have DNS
when the L2TP tunnel is down.

/etc/network/interfaces
-----------------------

*Please read the comments* in the example below. They are important. You must
adapt the config below for your purposes:

```
# The loopback network interface
auto lo
iface lo inet loopback

# a&a offers a /29 for l2tp but they gave me a /28; for a /29, you should
# use netmask 255.255.255.248, but in my case i specified 255.255.255.240

auto eth0
allow-hotplug eth0
iface eth0 inet static
       address 192.168.0.101
       netmask 255.255.255.0
       network 192.168.0.0
       # gateway 192.168.0.1 # we will set a custom route instead. see below
       broadcast 192.168.0.255
       up /sbin/ip route add 90.155.53.19/32 via 192.168.0.1 dev eth0

# LAN
auto eth1
iface eth1 inet static 
   address 81.187.172.129
   netmask 255.255.255.240 
   dns-nameservers 217.169.20.20 217.169.20.21

iface eth1 inet6 static 
   address  2001:8b0:b95:1bb5::1
   netmask 64 
   dns-nameservers 2001:8b0::2020 2001:8b0::2021
```

NOTE: IP address `90.155.53.19` is what `l2tp.aa.net.uk` resolves to, and it
shall be used directly for our purposes, due to absent name resolution during
initialisation of this network, when setting up L2TP. The static route that
we set, on `eth0`, ensures that we do have internet on the WAN side (to
the main ISP, not A&A), assuming that the (physical) main network itself works.

Enabling IP forwarding
======================

You must permit packet forwarding, so that traffic can flow between the two
network interfaces. Edit this file:

/etc/sysctl.conf
----------------

Uncomment this line:

	#net.ipv4.ip_forward=1
 
And this line (NOTE: disables stateless address autoconfiguration)

	#net.ipv6.conf.all.forwarding=1

The lines should then look like this:

	net.ipv4.ip_forward=1
	net.ipv6.conf.all.forwarding=1

Now run:

	sysctl -p

The last command simply applies it *now*, but this would also apply during
every booting of your system.

L2TP
====

It may seem counter-intuitive, that we're configuring PPP as though we're
on a hardline, but this is important for the next step. A&A provides L2TP
without authentication, but then you authenticate via PPP routed through L2TP.
It is through PPP that your (public) IP addresses are assigned, when you use
A&A. Such is also true of their hardline servers (e.g. VDSL/FTTP).

Debian kernels should already have the correct modules, but otherwise you must
ensure that the `CONFIG_PPPOL2TP` and `CONFIG_L2TP` options are enabled in
your kernel configuration.

It should be noted that A&A L2TP service is (as of this day) currently without
IPSEC or other encryption such as wireguard. This is less than ideal, but you
will likely be doing a lot of encrypted things online anyway (lots of websites
are https-aware nowadays).

*As a result* of plain L2TP being used, you can get away with hosting this on
very weak hardware, and still get full speed. One day, I might write guides
for how to use L2TP with, say, IPSEC enabled (using something other than A&A
for the upstream L2TP service).

You will not be able to use DNS until the L2TP is up, so we will use A&A's IP
address for `l2tp.aa.net.uk` directly, which is `90.155.53.19`.

/etc/xl2tpd/xl2tpd.conf
-----------------------

Place the following contents:

```
[lac aaisp]
lns = 90.155.53.19
require authentication = no
pppoptfile = /etc/ppp/options.aaisp
```

/etc/ppp/options.aaisp
----------------------

Create this file, and place the following contents:

NOTE: the `name` and `password` entries are your A&A login details for L2TP.

```
+ipv6
ipv6cp-use-ipaddr
name xyz@a.X
password Your_xyz@A.X_password
noauth
ifname ppp-aaisp-l2tp
```

ppp ifupdown scripts
====================

PPP and L2TP are managed by `pppd`, which executes if up/down scripts when
interfaces go up or down. We shall manipulate this accordingly:

/etc/ppp/ipv6-up.d/0000-defaultroute
------------------------------------

This file sets a default route on IPv6, but it can be (ab)used in general
to handle L2TP/PPP going up/down. This file is for when the link goes *up*.
A default route must be set!

The file should contain this logic:

```
#!/bin/bash
/bin/logger $1 is up
if [ $1 = "ppp-aaisp-l2tp" ]; then
	/bin/logger "AAISP over L2TP circuit is online; adding routes"
	/sbin/ip route add default dev ppp-aaisp-l2tp scope link
	/sbin/ip -6 route add default dev ppp-aaisp-l2tp scope link
fi
```

Don't forget to make it *executable*:

	chmod 755 /etc/ppp/ipv6-up.d/0000-defaultroute

/etc/ppp/ipv6-down.d/0000-defaultroute
--------------------------------------

The routes must be deleted, when the line goes down:

```
#!/bin/bash
/bin/logger $1 is down
if [ $1 = "ppp-aaisp-l2tp" ]; then
	/bin/logger "AAISP over L2TP circuit is offline; removing routes"
	/sbin/ip route del default dev ppp-aaisp-l2tp scope link
	/sbin/ip -6 route del default dev ppp-aaisp-l2tp scope link
fi
```

Don't forget to make *this* executable aswell:

	chmod 755 /etc/ppp/ipv6-down.d/0000-defaultroute

xl2tpd control file
===================

You may notice that we have, thus far, not specified any way in which
the L2TP tunnel connection is actually *started*. This will now be explained.

Create the xl2tpd control file:

	mkdir -p /var/run/xl2tpd
	touch /var/run/xl2tpd/l2tp-control

Start the xl2tpd service:

	systemctl start xl2tpd

Enable it at every boot:

	systemctl enable xl2tpd

We now have the L2TP daemon starting automatically at boot time, but it
will *not* automatically bring up your connection. The *daemon* monitors
writes to a *control file*, which we just created
at `/var/run/xl2tpd/l2tp-control`.

Tell the daemon to connect to aaisp:

	echo "c aaisp" > /var/run/xl2tpd/l2tp-control

To stop the L2TP connection, do this:

	echo "d aaisp" > /var/run/xl2tpd/l2tp-control

By running `ip a`, you will see the tunnel connection listed
as `ppp-aaisp-l2tp`, but only when the PPP (over L2TP) connection is active.
As you saw earlier, we went through the ifup/down scripts in Debian, that
add/remove routes.

You need to decide whether you want L2TP automatically starting in your router.
In some situations, it may not actually be desirable for it to autostart,
like if you just want to quickly test a new network but aren't ready for it
to go in production yet.

Debugging
---------

You can find useful logs in `/var/log/messages`, for `xl2tpd`.

Auto-connect
============

Re-try every minute
-------------------

Due to the way xl2tpd works (control files), I concluded that the best
way to handle this is with crontab. As root, do:

	crontab -e

In there, insert:

```
* * * * * echo "c aaisp" > /var/run/xl2tpd/l2tp-control
```

You might also add something like this, for resolving domain names:

```
* * * * * echo "nameserver 217.169.20.20" > /etc/resolv.conf
```

This L2TP routing setup is a bit hacky, and this guide could use some
refinement. The rule for `resolvconf`, as above, simply keeps DNS working.
The nameserver IP used, in the above example, is provided by A&A for customers.

Running the command when L2TP is up does nothing, and xl2tpd will simply exit
on that run, while the tunnel remains open. When the tunnel is down, running
that command will bring it back up.

Re-try *every 5 seconds*
------------------------

If your connection frequently has drop-outs of a few seconds, xl2tpd re-running
every minute will give you a lot more unnecessary down time.

It may be advisable to run every 5 seconds instead. The `crontab` file does not
provide for this, allowing only *per minute* instructions in our case.

You might simply run a script at boot time, that does it in a five-second loop.
For example:

```
#!/bin/sh

while true
do
	echo "c aaisp" > /var/run/xl2tpd/l2tp-control
	sleep 5
done
```

A more intelligent way might be to put, in the ifdown script as above, an
instruction to run the above loop, but make the loop exit when the tunnel
is up. That same modified script would also run at boot time. In this way,
you might save an extra second or two, but I wouldn't bother.

How to use internet (on hosts)
===================

Physical setup
--------------

You can simply hook up an ethernet switch, to the 2nd interface on your
router, the one that has allocated IPv4/6 subnet addresses on it as
per `/etc/network/interfaces`. Your host will then connect to that switch.

On that ethernet switch, you will then set your host(s) to use an IP address
from the /28 or /29 IPv4 subnet. You may even have a bigger subnet than that,
if you asked A&A nicely. You can also use IPv6, but without SLAAC; simply set
as many static IPv6 addresses that you want, on the host.

IP configuration (in your OS, for the host)
-------------------------------------------

With this routing setup, dual stack IPv4 and IPv6 is possible, for any
host connected to it.

The internet should Just Work on the router itself. No DHCP or NAT is running,
in this configuration; perhaps a guide could be written for *that*, but for this
exact setup as described on the page, you can simply specify the following
as static IP address:

* IP (host): any unused IP address (v4 or v6) on the subnet A&A gave you.
  Example (for libreboot.org): `81.187.172.132` and `2001:8b0:b95:1bb5::4`
* gateway: the IP of the L2TP router, on LAN side. In the example above,
  this would be `81.187.172.129` and `2001:8b0:b95:1bb5::1`
* netmask (IPv4): `255.255.255.240` on my /28 subnet. If you have a /29,
  it should be `255.255.255.248`
* broadcast (IPv4): in my case, I'm on `81.187.172.128/28`, so the broadcast
  address would be `81.187.191.143`; 128 is 10000000 in binary, and 32-28 is
  4, so we mask the 4 least significant bits which becomes 10001111, which is 143.
  You need to do the maths, for your specific IP and subnet size.
* prefix (IPv6): 64

DNS
---

Again, there is no DHCP on this network; additionally, we are not running
a DNS resolver (you *could* run one, if you wish). You must specify one
manually. Many resolvers exist. A&A provide them, for customers:

* `217.169.20.20`
* `217.269.20.21`
* `2001:8b0::2020`
* `2001:8b0::2021`

Security
========

You should configure SSH to accept keys only and (optional) only listen on
a local IP address (e.g. 10 network). This is beyond the scope of the article,
but it's quite trivial to set up.

e.g.

	ListenAddress 10.0.0.42

Testing
=======

The following commands may be useful later, to debug issues:

```
ip route
ip -6 route
ping 8.8.8.8
ping6 2001:4860:4860::8888
tcpdump -ni eth1
```

Other configuration to consider
===============================

MTU
---

Your main ISP (that you use to then run L2TP through) most likely doesn't
support higher than 1500 MTU, if that. Your L2TP connection will add bytes
in a frame, so the encapsulated PPP connection will have a lower MTU. There
is no way to avoid this, unless you have a hypothetical ISP that can give you,
say, 1540 MTU or something like that.

Anyway, the result is that your packets *will* be fragmented. In your A&A
control panel login (see: <https://control.aa.net.uk/>), you can set MTU
manually but I just recommend leaving it on auto.

If you see an MTU of, say, 1460, on your PPP connection (when SSH'd into the
router and running `ip a` or something), don't worry, it's normal. Just let
your router handle it, it's what Linux was born to do.

PTR records for IPs
-------------------

Sometimes called *reverse DNS*.

In an IP address, the PTR record resolves back to an arbitrary domain name
which can be set. Typically, your ISP will assign one and that's all you get,
but A&A lets you change it in the control panel: <https://control.aa.net.uk/>

You must get your domain name added to your login, even if it's not actually
registered with A&A. Simply email their tech team and ask them to do it. You
could also just ask them to set the PTR records.

For example, A/AAAA records in your DNS for `foo.bar.com` might point to one
of your IPs, and then you'd make that IP point back to `foo.bar.com`. You can
do this for an IPv4 and an IPv6 address that A&A assigns to you.

This can be very useful when running mail servers, precisely because you can make
the same entry for both IPv4 and IPv6. For example, my mail server has
the PTR record, on IPv4 and IPv6, of `libreland.libreboot.org` and I specify
this in my mail server plus DNS server configurations; the IP is also set
in my SPF record, with A/AAAA records for that IP pointing
to `libreland.libreboot.org`, so that everything matches up. This, plus other
things like setting proper DKIM record, is essential when running a mail
server, because a lot of services (like GMail) will block you on suspicion
of spam if these are misconfigured.

My next guide may in fact be how to set up a mail server! Also DNS and web,
etc.

Firewall
--------

I will not configure a firewall on this network. I always get an IPv4 subnet
from a&a either on hardlines or L2TP, and I run an open network. The router
is always hardened to only allow local SSH connections, or SSH turned off, for
security.

No NAT/DHCP either. If local hosts want to firewall themselves, they can, and
they can provide that stuff. I really don't see the point in using DHCP for
public IPv4 subnets.

If I want NAT/DHCP inside such a network, I usually plug in an OpenWRT router
and set a static IP on the WAN port for that. I also use OpenWRT routers to
in this way, when I want to set up a WiFi connection behind A&A.

Essentially, I like my main network to be "invisible". Just plug in and set an
IP (from the public subnet) and you're good to go. This assumes you have good
physical security and/or you trust the people that have access to it.

In short, this is a *real internet connection*. Anything you plug into this
network will be *directly on
the internet*. You should consider your security model, when doing this. It
is especially important to consider physical security; who do you trust, if
you're running this at your company (or even your own home)?

You should not connect anything insecure directly to this main network. For
iexample, your playstation or proprietary shitware Windows PC are not to be
trusted. A secure linux/BSD machine, assuming you're competent, is absolutely
fine. This setup is intended for sysadmins who really want to host lots
of servers on their home network.

Traffic shaping / QoS
---------------------

You might configure `codel` which is nice for QoS but that's beyond the scope
of this article.

tmpfs (/etc/fstab)
------------------

The `/tmp`, `/var/run` and `/var/lock` directories should also be tmpfs.
This isn't strictly necessary, but for a high-performance machine it might
be desirable, especially for something like this.

If you're running this on *really slow hardware*, you might consider that,
but you must also take *memory usage* into account when relying on tmpfs.
